package in.muton.edushare.poll.questions;

import in.muton.edushare.pages.EduShareBasePage;
import in.muton.edushare.wicket.models.CayenneModel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import com.edushare.common.dao.UserPollDAO;
import com.edushare.common.vo.PollOptions;
import com.edushare.common.vo.PollQuestions;

public class PreferencesQuestion extends QuestionBase {
	private static final long serialVersionUID = -1298261922526226636L;

	public PreferencesQuestion(String id, IModel<PollQuestions> model,
			EduShareBasePage page, final boolean preview, final boolean editMode) {
		super(id, model, page, preview, editMode);

		final List<PollOptions> poList = getQuestionModel().getObject()
				.getOptions();
		Collections.sort(poList);
		List<IModel<PollOptions>> sortedList = new ArrayList<IModel<PollOptions>>();
		for (final PollOptions p : poList) {
			TextField<Integer> tf;
			CayenneModel<PollOptions> tempModel;

			fieldMap.put(tempModel = new CayenneModel<PollOptions>(p),
					tf = new TextField<Integer>("preference",
							new Model<Integer>() {
								@Override
								public Integer getObject() {
									return i;
								}

								public void setObject(Integer i) {
									this.i = i;
								}

								private Integer i = p.getSerialNo() + 1;
								private static final long serialVersionUID = 4988003980491424111L;
							}));
			sortedList.add(tempModel);
			UserPollDAO upDAO = new UserPollDAO(getORMInterface());
			int pref = upDAO.getPreference(getLoggedInUser(),
					getQuestionModel().getObject(), p);
			if (pref != -1)
				tf.setModelObject(pref);
		}

		add(new ListView<IModel<PollOptions>>("optionList", sortedList) {
			private static final long serialVersionUID = 286372665924118868L;

			@Override
			protected void populateItem(ListItem<IModel<PollOptions>> arg0) {
				final PollOptions po = arg0.getModelObject().getObject();
				arg0.add(new Label("serialNum", Integer.toString(po
						.getSerialNo() + 1)));
				arg0.add(new Label("optName", po.getOptionString()));
				TextField<Integer> tf = fieldMap.get(arg0.getModelObject());
				arg0.add(tf);
				tf.setType(Integer.class);
				fieldMap.put(arg0.getModelObject(), tf);
			}
		});
	}

	private HashMap<IModel<PollOptions>, TextField<Integer>> fieldMap = new HashMap<IModel<PollOptions>, TextField<Integer>>();

	@Override
	public boolean retrieveValues() {
		UserPollDAO upDAO = new UserPollDAO(getORMInterface());
		List<PollOptions> poList = getQuestionModel().getObject().getOptions();
		for (PollOptions po : poList) {
			Integer i = upDAO.getPreference(getLoggedInUser(),
					getQuestionModel().getObject(), po);
			if (i == -1)
				return false;
		}
		return true;
	}

	@Override
	public boolean save(boolean draft) {
		if (isPreview() || isEditMode())
			return false;
		if (!verify())
			return false;
		HashMap<PollOptions, Integer> ansMap = new HashMap<PollOptions, Integer>();
		Set<Entry<IModel<PollOptions>, TextField<Integer>>> set = fieldMap
				.entrySet();
		for (Entry<IModel<PollOptions>, TextField<Integer>> s : set) {
			ansMap.put(s.getKey().getObject(), s.getValue().getModelObject());
		}
		new UserPollDAO(getORMInterface()).setPreferences(getLoggedInUser(),
				getQuestionModel().getObject(), ansMap);
		return true;
	}

	@Override
	public boolean verify() {
		Set<Entry<IModel<PollOptions>, TextField<Integer>>> set = fieldMap
				.entrySet();
		int[] checkBucket = new int[fieldMap.size() + 1];
		for (Entry<IModel<PollOptions>, TextField<Integer>> e : set) {
			Integer i = e.getValue().getModelObject();
			if (i < 1 || i > fieldMap.size()) {
				setError("Responses to question no. "
						+ getQuestionModel().getObject().getQuestionSerialNo()
						+ " should be numbers between 1 and " + fieldMap.size());
				return false;
			}
			if (checkBucket[i] == 0) {
				checkBucket[i] = i;
			} else {
				setError("Preferences for question no. "
						+ getQuestionModel().getObject().getQuestionSerialNo()
						+ " should be unique.");
				return false;
			}
		}
		return true;
	}

	@Override
	public void clear() {
		new UserPollDAO(getORMInterface()).clearAnswers(getLoggedInUser(),
				getQuestionModel().getObject());
		Set<Entry<IModel<PollOptions>, TextField<Integer>>> set = fieldMap
				.entrySet();
		for (Entry<IModel<PollOptions>, TextField<Integer>> e : set) {
			e.getValue().setModelObject(e.getKey().getObject().getSerialNo());
		}
	}
}
